----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    12:35:38 03/10/2012 
-- Design Name: 
-- Module Name:    IOInterface - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.definitions.all;


entity IOInterface is
    Port ( instr_ack_i : in  STD_LOGIC;
           instr_word_i : in  STD_LOGIC_VECTOR (17 downto 0);
           data_ack_i : in  STD_LOGIC;
           data_word_i : in  STD_LOGIC_VECTOR (7 downto 0);
           port_ack_i : in  STD_LOGIC;
           port_word_i : in  STD_LOGIC_VECTOR (7 downto 0);
			  cu_status : in state_type;
			  cu_mem_op : in STD_LOGIC;
			  ena_mem_port_data : in STD_LOGIC;
			  mem_rw : in STD_LOGIC;
			  datapath_word_o : in STD_LOGIC_VECTOR (7 downto 0);
			  datapath_addr_o : in STD_LOGIC_VECTOR (7 downto 0);
			  
			  pc: in  STD_LOGIC_VECTOR (9 downto 0);
			  		  
			  instr_reg : out STD_LOGIC_VECTOR (17 downto 0);
			  data_reg : out STD_LOGIC_VECTOR (7 downto 0);
           instr_cyc_o : out  STD_LOGIC;
           instr_stb_o : out  STD_LOGIC;
           instr_addr_o : out  STD_LOGIC_VECTOR (9 downto 0);
           data_cyc_o : out  STD_LOGIC;
           data_stb_o : out  STD_LOGIC;
			  data_we_o : out STD_LOGIC; 
           data_addr_o : out  STD_LOGIC_VECTOR (7 downto 0);
           data_word_o : out  STD_LOGIC_VECTOR (7 downto 0);
           port_cyc_o : out  STD_LOGIC;
           port_stb_o : out  STD_LOGIC;
           port_we_o : out  STD_LOGIC;
           port_addr_o : out  STD_LOGIC_VECTOR (7 downto 0);
           port_word_o : out  STD_LOGIC_VECTOR (7 downto 0);
			  instr_ack_to_cu : out STD_LOGIC;
			  data_ack_to_cu : out STD_LOGIC;
			  port_ack_to_cu : out STD_LOGIC);
end IOInterface;

architecture Behavioral of IOInterface is
begin

es_fetch: process(cu_status, instr_ack_i, instr_word_i, pc)
begin
	instr_reg <= instr_word_i;
	instr_addr_o <= pc;
	instr_ack_to_cu <= instr_ack_i;
	if(cu_status = FETCH) then --estado de fetch
		instr_cyc_o <= '1';
		instr_stb_o <= '1';
	else
		instr_cyc_o <= '0';
		instr_stb_o <= '0';
	end if;	
end process;	
		
		
es_mem: 	process(cu_status, cu_mem_op, datapath_addr_o, datapath_word_o, mem_rw,
					  data_ack_i, data_word_i, port_ack_i, port_word_i)
begin
	if((cu_status = EXECUTE and cu_mem_op = '1') or cu_status = MEM) then --estado EXECUTE de una instruccion mem, o estado MEM

		if(mem_rw = '1') then 			-- operacion de STORE/OUT
			if(ena_mem_port_data = '0') then -- operacion sobre la memoria de DATOS: store
				data_addr_o <= datapath_addr_o;
				data_word_o <= datapath_word_o;
				data_ack_to_cu <= data_ack_i;
				data_we_o <= mem_rw;
				data_cyc_o <= '1';
				data_stb_o <= '1';
			else 										-- operacion sobre la memoria de PORT: out
				port_addr_o <= datapath_addr_o;
				port_word_o <= datapath_word_o;
				port_ack_to_cu <= port_ack_i;
				port_we_o <= mem_rw;
				port_cyc_o <= '1';
				port_stb_o <= '1';
			end if;
		else 									-- operacion de LOAD/IN
			if(ena_mem_port_data = '0') then -- operacion sobre la memoria de DATOS: load
				data_reg <= data_word_i;
				data_addr_o <= datapath_addr_o;
				data_ack_to_cu <= data_ack_i;
				data_we_o <= mem_rw;
				data_cyc_o <= '1';
				data_stb_o <= '1';
			else 										-- operacion sobre la memoria de PORT: in
				data_reg <= port_word_i;
				port_addr_o <= datapath_addr_o;
				port_ack_to_cu <= port_ack_i;
				port_we_o <= mem_rw;
				port_cyc_o <= '1';
				port_stb_o <= '1';
			end if;
		end if;
	else
		port_cyc_o <= '0';
		port_stb_o <= '0';
		data_cyc_o <= '0';
		data_stb_o <= '0';
	
	end if;
end process;

end Behavioral;
